#include <msp430g2231.h>

#define SERIAL 

#ifdef SERIAL
#define     TXD                   BIT1                      // TXD on P1.1
#define     RXD                   BIT2                      // RXD on P1.2
unsigned short Bitime = 185; // (15.25 MHz/8) / 9600 = 185 counts/bit
unsigned char BitCnt;
unsigned char TXByte;
#endif

void ConfigureSPI(void)
{
	USICTL0 |= USIPE5 + USIPE6 + USIPE7 + USIMST + USIOE;
	USICTL0 &= ~USISWRST;
	USICTL1 = USICKPH;
	USICKCTL = USIDIV_4 + USISSEL_3 + USISWCLK;
	USISRH = 0;
	P1DIR |= 0x10; // P1.4 is output
	P1OUT |= 0x10; // Set SS to high
}

#ifdef SERIAL
void ConfigureTimerUart(void)
{
  CCTL0 = OUT;                               // TXD Idle as Mark
  TACTL = TASSEL_2 + MC_2 + ID_3;            // SMCLK, continuous mode, /8
  P1SEL |= TXD + RXD;                        //
  P1DIR |= TXD;                              //  
}
#endif

void init(void)
{
	WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
	// DCOx = 3, RSELx = 15 -> DCO = 15.25 MHz
	DCOCTL = 0x60; // DCOx = 3, MODx = 0
	BCSCTL1 = 0x1f; // RSELx = 15
	//TACTL = 0x0222; // SMCLK, continuous mode, enable interrupt
  //BCSCTL1 = CALBC1_1MHZ;                    // Set range
  //DCOCTL = CALDCO_1MHZ;
  //BCSCTL2 &= ~(DIVS_3);                         // SMCLK = DCO / 8 = 1MHz  


	//P1SEL |= 0x06; // P1.1 = TA0.0, P1.2 = TA0.CCI1A  
	//P1DIR |= 0x02;
#ifdef SERIAL
	ConfigureTimerUart();
#endif
	ConfigureSPI();
}

#ifdef SERIAL
// Function Transmits Character from TXByte 
void Transmit()
{ 
  BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
  while (CCR0 != TAR)                       // Prevent async capture
    CCR0 = TAR;                             // Current state of TA counter
  CCR0 += Bitime;                     // Some time till first bit
  TXByte |= 0x100;                        // Add mark stop bit to TXByte
  TXByte = TXByte << 1;                 // Add space start bit
  CCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
  while ( CCTL0 & CCIE );                   // Wait for TX completion
}

#pragma vector=TIMERA0_VECTOR
__interrupt void SerialTxInterrupt(void)
{
	CCR0 += Bitime;
    if (CCTL0 & CCIS0)                        // TX on CCI0B?
    {
      if ( BitCnt == 0)
        CCTL0 &= ~ CCIE;                        // All bits TXed, disable interrupt
      else
      {
        CCTL0 |=  OUTMOD2;                    // TX Space
        if (TXByte & 0x01)
        CCTL0 &= ~ OUTMOD2;                   // TX Mark
        TXByte = TXByte >> 1;
        BitCnt --;
      }
    }
}

void TxHex(unsigned short num)
{
	static unsigned char hex2ascii[] = "0123456789ABCDEF";
	TXByte = hex2ascii[(num & 0xf000) >> 12];
	Transmit();
	TXByte = hex2ascii[(num & 0x0f00) >> 8];
	Transmit();
	TXByte = hex2ascii[(num & 0x00f0) >> 4];
	Transmit();
	TXByte = hex2ascii[(num & 0x000f)];
	Transmit();
}

void TxShort(unsigned short num)
{
	TXByte = '0' + num/10000;
  	Transmit();
  	num %= 10000;
	TXByte = '0' + num/1000;
  	Transmit();
  	num %= 1000;
  	TXByte = '0' + num/100;
  	Transmit();
  	num %= 100;
  	TXByte = '0' + num/10;
  	Transmit();
  	num %= 10;
  	TXByte = '0' + num;
	Transmit();
}

void TxString(char * s)
{
	char * p;
	for(p = s; *p != '\0'; p++) {
		TXByte = *p;
		Transmit();
	}
}
#endif /* SERIAL */
unsigned char spi(unsigned char c)
{
	unsigned char rx;

	USISRL = c;
	USICNT = 8;
	
	while((USICTL1 & USIIFG) == 0);
	rx = USISRL;
	return rx;
}

int main(void)
{
	init();
  //P1DIR |= 0x01;                        // Set P1.0 to output direction
	__enable_interrupt();
  
	TxString("Hello, world!\r\n");
	P1OUT &= ~0x10;
	TxHex(spi(0x30)); // SNOP, get status byte	 
	TxHex(spi(0x31)); // SFSTXON, enable and calibrate freq synth
	TxHex(spi(0x35)); // SRX, enable RX
	P1OUT |= 0x10;
	while(1) {
	P1OUT &= ~0x10;
	TxString("Status byte: ");
	TxHex(spi(0x3d));
	TxString("\r\n");
	TxString("Partnum: ");
	spi(0xf0);
	TxHex(spi(0x00));
	TxString(" Version: ");
	spi(0xf1);
	TxHex(spi(0x00));
	
	TxString("\r\n");
	P1OUT |= 0x10;
	}	 
	//volatile unsigned int i;            // volatile to prevent optimization

	//P1OUT ^= 0x01;                      // Toggle P1.0 using exclusive-OR
	//i = 2;                          // SW Delay
	//do i--;
	//while (i != 0);
}
